/*
 * Created on 9-Jul-06 Filename: OrderCommand.java @author Daniel Yule
 */
package com.danicsoft.daide.command;

import com.danicsoft.daide.command.OrderSpec;
import com.danicsoft.daide.command.Turn;
import com.danicsoft.daide.token.StandardToken;
import com.danicsoft.daide.token.TokenMap;
import com.danicsoft.daide.token.TokenMap.Commands;
import com.danicsoft.daide.token.TokenGroup;

/**
 * Implements the ORD command. From Eric Wald's <a
 * href="http://pydip.brainshell.org/docs/syntax.html">protocol specification</a>,
 * v0.14:
 * <h4><a name="ORD">server_message = ORD</a> (turn) (order) (result)</h4>
 * <p>
 * This is sent by the server when the turn has processed. <b>turn</b> is the
 * turn which has just processed, with the same format as in the <b>Now </b>
 * command.
 * </p>
 * <p>
 * <b>order</b> is an order performed by a player. One <b>ORD</b> message is
 * sent per unit for a movement phase, one per retreat for a retreat phase, and
 * one per build, disband, or waive for a build phase. It has exactly the same
 * format as in the <b>SUB</b> and <b>THX</b> commands<!--, except that
 * loosely-specified orders will use a more rigorous format-->.
 * </p>
 * <p>
 * <b>result</b> is the result of the order. It can be one of the following:
 * </p>
 * <ul>
 * <!--
 * <h4>result = order_result</h4>
 * -->
 * <li><b>order_result = SUC</b> &mdash; Order succeeded</li>
 * <li><b>order_result = BNC</b> &mdash; Move bounced</li>
 * <li><b>order_result = CUT</b> &mdash; Support cut</li>
 * <li><b>order_result = DSR</b> &mdash; Move via convoy failed due to
 * dislodged convoying fleet</li>
 * <li><b>order_result = NSO</b> &mdash; No such order (for a support,
 * convoying fleet, or convoyed army)</li>
 * <!--
 * <h4>{AOA} order_result = note</h4>
 * -->
 * </ul>
 * <p>
 * In addition, a second token may be included:
 * </p>
 * <ul>
 * <!--
 * <h4>result = order_result RET</h4>
 * -->
 * <li><b>RET</b> &mdash; Unit was dislodged and must retreat.</li>
 * </ul>
 * <!--
 * <h4>result = RET</h4>
 * -->
 * <p>
 * In the case of a unit which was convoying or holding, <b>RET</b> may be the
 * only token.
 * </p>
 * <p>
 * Retreat orders will always have a <b>result</b> of <b>SUC</b> or <b>BNC</b>.
 * <b>BNC</b> indicates the unit was destroyed by a bounced retreat.
 * </p>
 * <p>
 * Build orders will always have a <b>result</b> of <b>SUC</b>.
 * </p>
 * <p>
 * Waived builds are reported as <b>(power WVE)</b> for the order. For example:
 * </p>
 * <p>
 * <b>ORD (WIN 1901) (RUS WVE) (SUC)</b>
 * </p>
 * <p>
 * If a power waives multiple builds, then multiple waive <b>ORD</b> messages
 * are sent.
 * </p>
 * <p>
 * When the turn processes, the series of <b>ORD</b> messages will be
 * immediately followed by a <b>SCO</b> (if the centre ownership has just been
 * updated) and a <b>NOW</b> message. The <b>NOW</b> message will always be
 * the last message in this sequence.
 * </p>
 * <p>
 * Turns may be skipped (for example, a retreat turn where nobody has any
 * retreats). The <b>NOW</b> message indicates which is the next turn.
 * </p>
 * <!--
 * <h4>client_request = ORD</h4>
 * -->
 * <p>
 * The previous turn's results may be requested by sending an <b>ORD</b>
 * command to the server with no parameters. The server will reply by resending
 * the last movement turn's <b>ORD</b> message, and any subsequent Retreat or
 * Build <b>ORD</b> messages, or <b>REJ (ORD)</b> if the game has not started
 * or the first turn has not yet processed.
 * </p>
 * 
 * @author Daniel Yule (daniel.yule@gmail.com)
 * @version 1.0
 */
public class OrderCommand extends QueryableCommand {

	/**
	 * The order that this command entails.
	 */
	private OrderSpec order;

	/**
	 * The turn this command occurs on.
	 */
	private Turn turn;

	/**
	 * The result of the submitted order.
	 */
	public StandardToken result;

	/**
	 * Construct a new <code>OrderCommand</code> from the tokens specified.
	 * 
	 * @param tokens
	 *        The <code>TokenGroup</code> this command will load from
	 * @throws ParseException
	 *         If there was a problem parsing the tokens.
	 */
	public OrderCommand(TokenGroup tokens) throws ParseException {
		super(tokens);
	}

	/**
	 * Constructs a new <code>OrderCommand</code> for querying the server.
	 */
	public OrderCommand() {
		super();
	}

	/**
	 * Construct a new <code>OrderCommand</code> for responding to submitted
	 * orders.
	 * 
	 * @param order
	 *        The order we are responding to.
	 * @param note
	 *        The note this order generated.
	 * @param turn
	 *        The turn this order is for.
	 */
	public OrderCommand(OrderSpec order, byte note, Turn turn) {
		super(false);
		this.order = order;
		this.result = TokenMap.getResultToken(note);
		this.turn = turn;

	}

	@Override
	public byte getType() {
		return Commands.ORD;
	}

	@Override
	public String toString() {
		return order.toString();
	}

	@Override
	public void doNonQueryIO(TokenIO tokenIO, TokenGroup tokens) throws ParseException {
		turn.doIO(tokenIO, tokens);
		order.doIO(tokenIO, tokens);
		result = (StandardToken) tokenIO.doToken(tokenIO.subGroup(tokens), result, TokenMap.results);

	}

	@Override
	public void initialize() {
		order = new OrderSpec();
		turn = new Turn();
		super.initialize();
	}

	/**
	 * Get the order for this comand.
	 * 
	 * @return The order for this command.
	 */
	public OrderSpec getOrder() {
		return order;
	}

}
